package com.ivideo.avcore.rtmplive;

import android.Manifest;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.util.Log;

import androidx.annotation.RequiresPermission;

/**
 * @author：lxy
 * @decription:音频采集
 * @time：2025/7/2
 */
public class AudioHelper {
    public static String TAG = "AudioRecord";
    private Config mConfig;

    private AudioHelper(Config config) {
        this.mConfig = config;
    }

    private volatile static AudioHelper instance;
    private byte[] buffer;

    public static AudioHelper getInstance(Config config) {
        if (instance == null) {
            synchronized (AudioHelper.class) {
                if (instance == null) {
                    instance = new AudioHelper(config);
                }
            }
        }
        return instance;
    }

    private AudioRecord mAudioRecord;

    /**
     * 初始化AudioRecorder
     */


    @RequiresPermission(Manifest.permission.RECORD_AUDIO)
    public Params initAudioRecord() {
        //最小缓冲区
        int buffsize = 2 * AudioRecord.getMinBufferSize(mConfig.sampleRate, mConfig.channelConfig, mConfig.audioFormat);
        //创建AudioRecorder
        mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, mConfig.sampleRate, mConfig.channelConfig, mConfig.audioFormat, buffsize);
        if (mAudioRecord.getState() != AudioRecord.STATE_INITIALIZED) {
            // 初始化失败处理
            Log.e("AudioRecord", "AudioRecord initialization failed");
            mAudioRecord.release();
            return null;
        }
        this.buffer = new byte[Math.min(4096, buffsize)];
        return new Params(mConfig.sampleRate, mConfig.channelConfig == AudioFormat.CHANNEL_CONFIGURATION_STEREO ? 2 : 1);
    }

    private Thread workThread;
    private boolean loop;

    /**
     * 开始录音
     */
    public void start() {
        workThread = new Thread() {
            @Override
            public void run() {
                mAudioRecord.startRecording(); //开始录音
                while (loop && !Thread.interrupted()) {
                    int size = mAudioRecord.read(buffer, 0, buffer.length);//读取数据
                    if (size < 0) {
                        Log.i("TAG", "audio ignore ,no data to read");
                        break;
                    }
                    if (loop) {
                        byte[] audio = new byte[size];
                        System.arraycopy(buffer, 0, audio, 0, size);
                        if (mCallback != null) {
                            mCallback.audioData(audio); //接口回调
                        }
                    }
                }

            }
        };

        loop = true;
        workThread.start();
    }

    public void stop() {
        loop = false;
        if (workThread != null) {
            workThread.interrupt();
        }

        if (mAudioRecord != null) {
            Log.i("TAG", "run: 调用stop");
            mAudioRecord.stop();
        }
    }

    public void release() {
        if (mAudioRecord != null) {
            mAudioRecord.release();
            mAudioRecord = null;
        }
    }

    private Callback mCallback;

    public void setCallback(Callback callback) {
        this.mCallback = callback;
    }

    public interface Callback {
        void audioData(byte[] data);
    }

    public static class Params {
        public final int sampleRate;
        public final int channelCount;

        public Params(int sampleRate, int channelCount) {
            this.sampleRate = sampleRate;
            this.channelCount = channelCount;
        }
    }
}
